iT邦幫忙

2021 iThome 鐵人賽

DAY 10
0
Modern Web

新新新手閱讀 Angular 文件30天系列 第 10

新新新手閱讀 Angular 文件 - Get data from a server(1) - Day10

  • 分享至 

  • xImage
  •  

學習目標

本文章將會是閱讀官方文件 Get data from a server 內容所做的筆記。
本章節會教如何透過 Angular 的 HTTP 功能,來取得、新增、編輯、刪除有關英雄的資料。

加入 HTTP 服務

Angular 是透過 HTTPClient 這個功能來達到發出 HTTP 請求來跟遠端伺服器互動。

Step1.
我們要在 AppModule 中引用 HttpClientModule 模組。並在 AppModule 的 imports 加入這個模組。

--- app.module.ts ---
import { HttpClientModule } from '@angular/common/http';

@NgModule({
  imports: [
    //...,
		HttpClientModule 
  ]
})

模仿與遠端伺服器取資料的情境

在官方文件中,提供了一個 In-memory Web API package 的模組,讓我們可以使用 Angular 的 HTTPClient 模組來跟 In-memory Web API package 取資料,來模仿與遠端伺服器取資料的情境。

這部分就跟這官方文件教的安裝 In-memory Web API package 的步驟,在你的專案中安裝這個套件,並在安裝完成之後,記得在 app.module.ts 中引入這個套件。

創出假的遠端資料庫資料

輸入指令 ng generate service InMemoryData,會發現在專案資料夾中出現 in-memory-data.service.ts 這個檔案,我們接下來就要在這個檔案中加入英雄資料的資料庫內容。

這邊的內容就是按照官方文件所給的內容加入到 in-memory-data.service.ts 檔案中就可以了,這邊就先不贅述了。

加入 http 功能

接下來,我們就在 HeroService 加入 HTTPClient 的功能,就可以在元件裡面透過它來發送 HTTP 請求囉。

Note:
有注意到嗎! 在 HeroService 所屬的模組 AppModule 我們先引入了 HttpClientModule ,接著,才在使用 http 請求的 HeroService 引入 HTTPClient ,才有辦法使用 HTTP 請求。

--- hero.service.ts ---
import { HttpClient, HttpHeaders } from '@angular/common/http';

@Injectable({ providedIn: 'root' })
export class HeroService {
  private heroesUrl = 'api/heroes';

  constructor (
    private http: HttpClient,
  ) {}
  
  /* 原本取得英雄資料的方法
  getHeroes(): Observable<HERO[]> {
     const heroes = of(HEROES);
     this.messageService.add('HeroService: fetched heroes');
     return heroes;
  }
  */
  
  getHeroes(): Observable<Hero[]> {
    return this.http.get<Hero[]>(this.heroesUrl)
  }
}

除了引入了 HttpClient 和 HttpHeaders。
也定義了目標資料庫的路徑 heroesUrl = 'api/heroes'
接著,將原本的 getHeroes 函式,改為用 http 的 get 方法從目標 url 中取回英雄資料。

HttpClient 方法會回傳一種值

所有的 HttpClient 的方法都會回傳屬於某個 Observable 實例的內容。

一般來說 RxJS 中的 Observable 是具有可以回傳好幾個數值的特性,但是,來自 HttpClient 的 Observable 就只會傳出一個值,並在傳出這個值之後,就不會再傳出任何值了。

錯誤處理

引入 catchError 和 pipe 模組,利用 pipe 將 catchError 模組的內容,接在某些取 API 回傳資料的程式後面,用以做錯誤處理的對應。

--- hero.service.ts ---
import { catchError, map, tap } from 'rxjs/operators';

getHeroes(): Observable<Hero[]> {
  return this.http.get<Hero[]>(this.heroesUrl)
    .pipe(
      catchError(this.handleError<Hero[]>('getHeroes', []))
    );
}
private handleError<T>(operation = 'operation', result?: T) {
  return (error: any): Observable<T> => {

    // TODO: send the error to remote logging infrastructure
    console.error(error); // log to console instead

    // Let the app keep running by returning an empty result.
    return of(result as T);
  };
}

透過 id 取的英雄資料

定義目標路徑為 api/heroes/id。前面的 baseUrl 我們再前面有定義過了,並將它設為變數 heroesUrl 的內容。後面的 id 就是要被獲取詳細資料的英雄的 id。

--- hero.service.ts ---
getHero(id: number): Observable<Hero> {
  const url = `${this.heroesUrl}/${id}`;
  return this.http.get<Hero>(url).pipe(
    catchError(this.handleError<Hero>(`getHero id=${id}`))
  );
}

這邊要注意,這邊的函式名稱是 getHero 其中 Hero 是單數,而上面的是 getHeroes 其中的 Heroes 是複數,兩者不相同喔,要注意一下~

Summary

這邊做一個小總結,到這邊我們知道了

  1. 引用 Angular 的 HttpClientModule 模組,就可以透過 http 來對遠端的伺服器做 CURD 的操作。
  2. 來自 httpclient.get 的 Observable 只會傳出一個值。
  3. 在要使用 HTTP 請求功能的模組中要引入 HttpClient 這個模組。接著,就可以利用 this.HttpClient.get 這種語法來執行 GET 的請求。
  4. 我們可以引入 catchError 模組,並將它 pipe 在某些 API 操作後面,負責錯誤處理。

上一篇
新新新手閱讀 Angular 文件 - Add Service(2) - Day09
下一篇
新新新手閱讀 Angular 文件 - Get data from a server(2) - Day11
系列文
新新新手閱讀 Angular 文件30天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言